#include "stdafx.h"
#include "RequestWorker.h"
#include "HttpClient.h"


RequestWorker::RequestWorker(bool destroySelfAfterFirstRequest) : destroySelf(destroySelfAfterFirstRequest)
{
	workThread = ::CreateThread(NULL, 0, work_entry, this, 0, NULL);
}

RequestWorker::~RequestWorker()
{
	::TerminateThread(workThread, 0);

	for(auto it = requests.begin(); it != requests.end(); ++it)
	{
		delete (*it);
	}
}

void RequestWorker::pushRequest(const SqlRequest &request)
{
	ScoupedLocker lock(requestsLocker);

	// copy request
	requests.push_back(new SqlRequest(request));
}

void RequestWorker::work()
{
	while(true)
	{
		while( currentRequest().empty() )
		{
			::Sleep(WAIT_REQUEST_PAUSE);
		}

		process( currentRequest() );
		nextRequest();
	}
}

void RequestWorker::process(const SqlRequest &request)
{
	SqlResponse & response = client.execute(request.request);
	HttpClient::send(response);
}

const SqlRequest & RequestWorker::currentRequest() const
{
	static SqlRequest empty;

	ScoupedLocker lock(requestsLocker);

	if ( !requests.empty() )
		return *requests[0];

	return empty;
}

void RequestWorker::nextRequest()
{
	ScoupedLocker lock(requestsLocker);

	if ( !requests.empty() )
		requests.erase(requests.begin());
}

// static
DWORD WINAPI RequestWorker::work_entry(LPVOID lpParameter)
{
	if (lpParameter)
	{
		RequestWorker *pThis = reinterpret_cast<RequestWorker*>(lpParameter);
		pThis->work();
	}

	return 0;
}
